<template>
  <div class="map-display">
    <div class="map-toolbars">
      <div class="address"></div>
      <div class="tool-box">
        <el-select v-model="paintType" size="mini">
          <el-option label="百度地图" value="baidu"></el-option>
          <el-option label="高德地图" value="gaode"> </el-option>
        </el-select>

        <ul class="tools">
          <li
            @click="mapType = mapType === 'satellite' ? 'normal' : 'satellite'"
          >
            {{ mapType === "satellite" ? "普通地图" : "卫星地图" }}
          </li>

          <li @click="showTraffic = !showTraffic">路况</li>
          <li @click="handleAraeSearch">区域查车</li>
          <li @click="handleTestDistance">测距</li>
          <li @click="handlePositionPoint">位置点</li>
          <li @click="handleEnclosure">围栏</li>
          <li @click="handleSecond">二押点</li>
        </ul>
      </div>
    </div>
    <div id="map"></div>

    <div class="status-info" :class="[infoClass[infoStatus]]">
      <div class="info-header">
        <div>
          <span>总:1</span>
          <span>在线:0</span>
          <span>离线:1</span>
        </div>
        <div>
          <i class="el-icon-more"></i>
          <i class="el-icon-arrow-up" @click="addInfoStatus"></i>
          <i class="el-icon-arrow-down" @click="reduceInfoStatus"></i>
        </div>
      </div>
      <div class="empty-box">
        <img src="/map-image/noneAlarm-msg.png" />
        <span class="empty-message"> 恭喜您，车辆暂无报警</span>
      </div>
    </div>
    <transition
      enter-active-class="animate__animated animate__slideInRight"
      leave-active-class="animate__animated animate__slideOutRight"
    >
      <div class="data-lists" v-show="showDataList">
        <div>
          <span style="color: #20A1FF;" class="list-title">{{
            dataListsSettings[dataListsType]["title"]
          }}</span>
          <div class="list-icon-button">
            <i class="el-icon-plus" @click="openDataListsDiaog"></i>
            <i class="el-icon-view"></i>
            <i class="el-icon-close" @click="showDataList = false"></i>
          </div>
        </div>

        <ul class="data-lists-body">
          <li
            v-for="(item, index) in dataLists[dataListsType]"
            :key="index"
            @click="handleDataListItemClick(item)"
          >
            {{ item.name }}
          </li>
        </ul>
      </div>
    </transition>

    <transition
      enter-active-class="animate__animated animate__slideInRight"
      leave-active-class="animate__animated animate__slideOutRight"
      ><div id="Panorama-box" v-show="showPanorama">
        <div id="Panorama"></div>
        <i
          class="Panorama-close el-icon-close"
          @click="showPanorama = false"
        ></i></div
    ></transition>

    <area-search-dialog ref="AreaSearch"></area-search-dialog>
    <position-point-dialog
      ref="PositionPoint"
      @submit="pushDataLists"
    ></position-point-dialog>
    <enclosure-dialog
      ref="EnclosureDialog"
      @submit="pushDataLists"
    ></enclosure-dialog>
    <second-dialog ref="SecondDialog" @submit="pushDataLists"></second-dialog>

    <div id="BdInfoWindow">
      <ul>
        <li>{{ carInfoWindow.data.deviceCode }} [WX01A-W / 电量:0.0%]</li>
        <li>速 度: 0km/h</li>
        <li>方向: 北</li>
        <li>信号时间: {{ carInfoWindow.expandData.recDate }}</li>
        <li>定 位: {{ carInfoWindow.expandData.PositioningType }}</li>
        <li>离 线: 21天22小时</li>
        <li>油电状态: 正常</li>
        <li>ACC状态: 开</li>
        <li>
          <span><i class="el-icon-s-tools"></i>轨迹</span>
          <span @click="openPanorama"><i class="el-icon-s-tools"></i>街景</span>
          <span><i class="el-icon-s-tools"></i>设置</span>
          <span><i class="el-icon-s-tools"></i>位置</span>
          <span><i class="el-icon-s-tools"></i>基站</span>
          <span><i class="el-icon-s-tools"></i>查流量</span>
          <span><i class="el-icon-s-tools"></i>关注度</span>
        </li>
      </ul>
    </div>

    <div id="GdInfoWindow">
      <ul>
        <li>14020843471 [WX01A-W / 电量:0.0%]</li>
        <li>速 度: 0km/h</li>
        <li>方向: 北</li>
        <li>信号时间: 2021-06-30 17:27:14</li>
        <li>定 位: 基 站</li>
        <li>离 线: 21天22小时</li>
        <li>油电状态: 正常</li>
        <li>ACC状态: 开</li>
        <li>
          <span><i class="el-icon-s-tools"></i>轨迹</span>
          <span @click="openPanorama"><i class="el-icon-s-tools"></i>街景</span>
          <span><i class="el-icon-s-tools"></i>设置</span>
          <span><i class="el-icon-s-tools"></i>位置</span>
          <span><i class="el-icon-s-tools"></i>基站</span>
          <span><i class="el-icon-s-tools"></i>查流量</span>
          <span><i class="el-icon-s-tools"></i>关注度</span>
        </li>
      </ul>
    </div>
  </div>
</template>

<script>
import baiduClass from "./mapjs/baiduClass";
import gaodeClass from "./mapjs/gaodeClass";
import AreaSearchDialog from "./area-search-dialog.vue";
import PositionPointDialog from "./position-point-dialog.vue";
import EnclosureDialog from "./enclosure-dialog.vue";
import SecondDialog from "./second-dialog.vue";
import Paho from "./paho-mqtt.js";

let toolsData = [
  // {
  //   label: "二押点",
  //   value: ""
  // }
];

let dataListsSettings = {
  positionPoint: {
    title: "位置点"
  },

  enclosure: {
    title: "围栏"
  },

  second: {
    title: "二押点"
  }
};

export default {
  name: "MapDisplay",
  components: {
    AreaSearchDialog,
    PositionPointDialog,
    EnclosureDialog,
    SecondDialog
  },

  data() {
    return {
      client: null,
      topic: "topic",
      carMarks: [],
      carMarksIndex: 0,

      infoClass: ["small-window", "", "large-window"],
      infoStatus: 0,
      carInfoWindow: {
        data: {
          deviceCode: ""
        },
        expandData: {
          PositioningType: "",
          recDate: ""
        }
      },
      dataListsType: "positionPoint",
      instance: null,
      showPanorama: false,
      showTraffic: false,
      araeSearch: false,
      showDataList: false,
      paintType: "baidu",
      mapType: "normal",
      dataLists: {
        positionPoint: [],
        enclosure: [],
        second: []
      },
      cancleRender: false,
      toolsData,
      dataListsSettings,
      carMarksTimer: null
    };
  },

  created() {},

  methods: {
    loadBaiduScript() {
      var script = document.createElement("script");
      let baseUrl =
        "https://api.map.baidu.com/api?v=3.0&ak=CtCjN4fQOfMkbI9UvaxBFCyLoZ5h9XRY&services=true&callback=initializeBaidu";
      script.src = baseUrl;
      document.body.appendChild(script);
    },

    loadGaodeScript() {
      var script = document.createElement("script");
      let baseUrl =
        "https://webapi.amap.com/maps?v=2.0&key=dade8b93e02e73546802e31ec0b1629f&callback=initializeGaode";
      let callback = this.paintType === "gaode" ? "&callback=initialize" : "";
      script.src = baseUrl + callback;
      document.body.appendChild(script);
    },

    loadBaiduPlugin(src) {
      var script = document.createElement("script");
      script.src = location.origin + location.pathname + src;
      document.body.appendChild(script);
    },

    initMap() {
      let constructor = this.paintType === "baidu" ? baiduClass : gaodeClass;
      this.instance = new constructor({
        vueInstance: this,
        type: this.paintType,
        mapType: this.mapType,
        showTraffic: this.showTraffic
      });

      function myFun(result) {
        var cityName = result.name;
        console.log(result);
        this.instance.map.setCenter(cityName);
        // alert("当前定位城市:" + cityName);
      }
      var myCity = new BMap.LocalCity();
      myCity.get(myFun.bind(this));

      this.instance.map.addEventListener("dragend", e => {
        this.clearMarkers();
      });

      this.instance.map.addEventListener("zoomend", e => {
        this.clearMarkers();
      });

      // this.instance.map.addEventListener("resize", e => {
      //   this.clearMarkers();
      // });

      this.connectClient();

      // this.showCar({
      //   point: {
      //     lat: 30.639720594619,
      //     lng: 104.004787055122
      //   }
      // });
    },

    connectClient() {
      this.client = new Paho.Client(
        "82.157.27.251",
        61614,
        "js-utility-KWuBy1"
      );
      this.client.connect({
        onSuccess: this.onConnect
      });
      this.client.onConnectedLost = this.onConnectedLost;
      this.client.onMessageArrived = this.onMessageArrived;
    },

    onConnectedLost(responseObject) {
      console.log("onConnectionLost:" + responseObject.errorMessage);
    },
    onMessageArrived(message) {
      // return;
      // console.log("onMessageArrived:" + message.payloadString);
      let data = JSON.parse(message.payloadString);

      let Bounds = this.instance.map.getBounds();
      // let point = new BMap.Point(data.expandData.longitude, data.expandData.latitude)
      // if (Bounds.containsPoint(point)) {

      // }

      let o = {
        latitude: data.expandData.latitude,
        longitude: data.expandData.longitude,
        data: data,
        expandData: data.expandData,
        point: {
          lng: data.expandData.longitude,
          lat: data.expandData.latitude
        }
      };

      window.requestAnimationFrame(() => {
        this.instance.addCarMark(o, this.carMarks.length, Bounds);
      });
      // console.log(this)

      this.carMarks.push(o);
      window.carMarks = this.carMarks;
      // console.log(this.carMarks);
    },
    onConnect() {
      // alert(1)
      // Once a connection has been made, make a subscription and send a message.
      console.log("onConnect");
      this.client.subscribe(this.topic);
    },

    areaSearchResult(startPonit, endPoint, isCover) {
      this.$refs.AreaSearch.show(isCover);
    },

    handleAraeSearch() {
      this.instance.paintPolygon();
    },

    handleTestDistance() {
      this.instance.testDistance();
    },

    handlePositionPoint() {
      this.dataListsType = "positionPoint";
      this.showDataList = true;
    },

    openDataListsDiaog() {
      switch (this.dataListsType) {
        case "positionPoint":
          this.$refs.PositionPoint.show();
          break;
        case "enclosure":
          this.$refs.EnclosureDialog.show();
          break;
        case "second":
          this.$refs.SecondDialog.show();
          break;
        default:
          breaks;
      }
    },

    //添加位置点数据
    pushDataLists(data) {
      this.dataLists[this.dataListsType].push(data);
    },

    handleDataListItemClick(item) {
      switch (this.dataListsType) {
        case "positionPoint":
          this.instance.addPositionMaker(item.point);
          break;
        case "enclosure":
          this.instance.addEnclosure(item.path);
          break;
        case "second":
          this.instance.addSecond(item.point, item.region);
          break;
        default:
          break;
      }
    },

    //处理围栏
    handleEnclosure() {
      this.dataListsType = "enclosure";
      this.showDataList = true;
    },

    handleSecond() {
      this.dataListsType = "second";
      this.showDataList = true;
    },

    showCar(data, index) {
      this.instance.addCarMark(data, index);
    },

    openPanorama() {
      this.showPanorama = true;
      this.$nextTick(() => {
        this.instance.openPanorama();
      });
    },

    addInfoStatus() {
      this.infoStatus === 2 ? (this.infoStatus = 0) : this.infoStatus++;
    },

    reduceInfoStatus() {
      this.infoStatus === 0 ? (this.infoStatus = 2) : this.infoStatus--;
    },

    setCarInfoWindow(val) {
      this.carInfoWindow = val;
    },

    clearMarkers() {
      if (this.carMarksTimer) {
        clearTimeout(this.carMarksTimer);
        this.carMarksTimer = null;
      }

      this.carMarksTimer = setTimeout(() => {
        let overlays = this.instance.map.getOverlays();
        let Bounds = this.instance.map.getBounds();

        let hasMap = Object.create(null);

        console.time("a");
        // overlays.forEach(o => {
        //   // console.log(o);
        //   if (o.yQ === "Marker") {
        //     if (!Bounds.containsPoint(o.point)) {
        //       // o.hide();
        //       setTimeout(() => {
        //         window.requestAnimationFrame(() => {
        //           this.instance.map.removeOverlay(o);
        //         });
        //       }, 100);
        //     } else {
        //       let position = o.getPosition();
        //       hasMap[`${position.lat}-${position.lng}`] = true;
        //     }
        //   }
        // });

        let overlaysLength = overlays.length;
        let that = this;

        while (overlaysLength >= 1) {
          overlaysLength -= 1;
          if (overlays[overlaysLength].yQ === "Marker") {
            if (!Bounds.containsPoint(overlays[overlaysLength].point)) {
              overlays[overlaysLength].hide();
              setTimeout(function(overlaysLength) {
                window.requestAnimationFrame(() => {
                  that.instance.map.removeOverlay(overlays[overlaysLength]);
                });
              }.bind(this, overlaysLength), 16);
            } else {
              let position = overlays[overlaysLength].getPosition();
              hasMap[`${position.lat}-${position.lng}`] = true;
            }
          }
        }

        console.timeEnd("a");

        // console.log(hasMap)
        // this.instance.map.clearOverlays();

        Promise.resolve().then(() => {
          console.time("b");

          let carMarksLength = this.carMarks.length;
          let that = this;

          while (carMarksLength >= 1) {
            carMarksLength -= 1;
            if (
              !hasMap[
                `${that.carMarks[carMarksLength].latitude}-${that.carMarks[carMarksLength].longitude}`
              ]
            ) {
              this.instance.addCarMark(
                this.carMarks[carMarksLength],
                carMarksLength,
                Bounds
              );
            } else {
            }
          }

          // this.carMarks.forEach((data, index) => {
          //   if (!hasMap[`${data.latitude}-${data.longitude}`]) {
          //     this.instance.addCarMark(data, index, Bounds);
          //   } else {
          //   }
          // });
          console.timeEnd("b");
        });
      }, 800);
    }
  },

  mounted() {
    if (!window.AMap || !window.BMap) {
      //改变地图加载完成后回调this的指向
      window.initializeBaidu = function() {
        this.paintType === "baidu" ? this.initMap() : "";
        this.loadBaiduPlugin("bdplugin/DrawingManager.min.js");
        this.loadBaiduPlugin("bdplugin/DistanceTool.min.js");
        this.loadBaiduPlugin("bdplugin/LuShu.min.js");
        this.loadBaiduPlugin("bdplugin/GeoUtils.min.js");
      }.bind(this);

      window.initializeGaode = function() {
        this.paintType === "gaode" ? this.initMap() : "";
      }.bind(this);

      //加载两个地图
      this.loadGaodeScript();
      this.loadBaiduScript();
      return;
    }

    this.initMap();
  },

  watch: {
    mapType: {
      immediate: false,
      handler(n) {
        this.instance.changeMapType(n);
      }
    },

    paintType: {
      immediate: false,
      handler(n) {
        this.initMap();
      }
    },

    showTraffic: {
      immediate: false,
      handler(n) {
        this.instance.toggleTrafficValue(n);
      }
    },

    carMarks() {
      // this.clearMarkers();
      // if (this.carMarksTimer) {
      //   clearTimeout(this.carMarksTimer);
      //   this.carMarksTimer = null;
      // }
      // this.carMarksTimer = setTimeout(() => {
      //   this.carMarks.forEach((data, index) => {
      //     // this.iaddCarMark
      //     if (index < this.carMarksIndex) {
      //       return;
      //     }
      //     this.instance.addCarMark(data, index);
      //     this.carMarksIndex = index;
      //   });
      // }, 500);
    }
  }
};
</script>

<style lang="scss">
.map-display {
  height: 100%;
  position: relative;

  .map-toolbars {
    height: 36px;
    background-color: #f9f9f9;
    border-bottom: 1px solid #e6e6e6;

    .tool-box {
      float: right;
      height: 36px;
      line-height: 36px;

      .el-select {
        width: 95px;
        margin-right: 8px;
      }
    }
  }

  .tools {
    display: inline-block;
    font-size: 13px;
    vertical-align: top;

    li {
      display: inline-block;
      padding: 0 10px;
      cursor: pointer;
      vertical-align: top;

      &:hover {
        background: #479de6;
        color: white;
      }
    }
  }

  #map {
    height: calc(100% - 36px);
  }

  .status-info {
    position: absolute;
    height: calc(100% - 36px);
    bottom: 10px;
    right: 10px;
    width: 100%;
    background: white;
    height: 300px;
    width: 500px;
    transition: all 0.5s linear;
    border-radius: 10px;

    &.small-window {
      height: 30px;
    }

    &.large-window {
      height: calc(100% - 36px);
      width: 100%;
      bottom: 0;
      right: 0;
    }

    .info-header {
      height: 30px;
      line-height: 30px;
      background: #20a0ff;
      color: white;
      font-size: 13px;
      display: flex;
      justify-content: space-between;
      padding: 0 10px;
      border-radius: 10px 10px 0 0;
      > div:first-child {
        span {
          margin-right: 10px;
        }
      }

      > div:last-child {
        i {
          margin-left: 10px;
          cursor: pointer;
        }
      }
    }

    .empty-box {
      width: 150px;
      height: 100px;
      display: flex;
      flex-direction: column;
      align-items: center;
      position: absolute;
      top: 60px;
      left: 50%;
      transform: translateX(-50%);

      img {
        width: 70px;
        height: 70px;
      }

      .empty-message {
        margin-top: 15px;
        font-size: 13px;
        color: #a9a9a9;
      }
    }
  }

  .data-lists {
    height: calc(100% - 36px);
    position: absolute;
    width: 300px;
    top: 36px;
    right: 0;
    z-index: 23;
    background: #fff;
    border-left: 1px solid #e6e6e6;

    > div:first-child {
      padding: 10px;
      font-size: 14px;
      border-bottom: 1px solid #e6e6e6;
    }

    .list-icon-button {
      float: right;

      i {
        margin-left: 10px;

        &:hover {
          color: #20a1ff;
          cursor: pointer;
        }
      }
    }
  }

  #Panorama-box {
    height: calc(100% - 0px);
    position: absolute;
    width: 500px;
    top: 36px;
    right: 0;
    z-index: 23;
    background: #fff;
    border-left: 1px solid #e6e6e6;

    #Panorama {
      width: 100%;
      height: 100%;
    }

    .Panorama-close {
      position: absolute;
      top: 10px;
      right: 10px;
      z-index: 25;
      background-color: white;
      font-size: 15px;
      display: inline-block;
      width: 20px;
      height: 20px;
      line-height: 20px;
      text-align: center;
      border-radius: 50%;
      cursor: pointer;
    }
  }

  .data-lists-body {
    li {
      height: 35px;
      line-height: 35px;
      padding: 0 8px;
      font-size: 13px;
      color: #555;
      cursor: pointer;

      &:hover {
        background: #f5f5f5;
      }
    }
  }

  #GdInfoWindow,
  #BdInfoWindow {
    width: 400px;

    li {
      font-size: 13px;
      line-height: 20px;
      &:first-child {
        border-bottom: 1px solid #e6e6e6;
        padding-bottom: 5px;
      }

      &:last-child {
        border-top: 1px solid #e6e6e6;
        padding-top: 5px;
        display: flex;
        justify-content: space-between;
        color: #067ec0;

        span {
          cursor: pointer;
        }
      }
    }
  }
}
</style>
